/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/*!
  \file commandStruct.h
  \brief header file for sensor communications

  \author Jack Elston
  $Date: 2005/09/07 20:51:43 $
*/

#ifndef __COMMANDSTRUCT_H
#define __COMMANDSTRUCT_H

#include <inttypes.h>
#include <arpa/inet.h>

/*<-------Defines--------->*/
/*! \brief	number of servos on the system. */
#define NUM_SERVOS 6
/*! \brief	number of neighbor nodes to track. */
#define SOEKRIS_MAX_LINKSTAT 8

#define CopyBufToStruct(buf, me) memcpy((char *)&me, buf, sizeof(me) )
#define CopyStructToBuf(me, buf) memcpy(buf, (char *)&me, sizeof(me) )

#define NUM_DEPLOY_MECHANISMS (10)
#define NAME_STRING_LEN (32)

/**********************\
|        servo         |
\**********************/
/*! \brief commanded servo positions. */
typedef struct {
	uint16_t channels[4];                //!< per channel command [1 to 65536]
} __attribute__ ((packed))Servos_t;

typedef struct {
	uint8_t channels[4];                 //!< 0 or 1 toggle
} __attribute__ ((packed))Buttons_t;

/**********************\
|         imu          |
\**********************/

typedef struct {
	int16_t roll;  // [milliradians]
	int16_t pitch; // [milliradians]
	int16_t yaw;   // [milliradians]
} __attribute__ ((packed))IMUAngles_t;

typedef struct {
	int16_t roll;  // [milliradians/s]
	int16_t pitch; // [milliradians/s]
	int16_t yaw;   // [milliradians/s]
} __attribute__ ((packed))IMURates_t;

typedef struct {
	int16_t x; // [milli-g]
	int16_t y; // [milli-g]
	int16_t z; // [milli-g]
} __attribute__ ((packed))IMUAccelerations_t;

typedef struct {
	IMUAngles_t angles;
	IMURates_t  rates;
	IMUAccelerations_t accelerations;
} __attribute__ ((packed))IMU_t;

/**********************\
|        gps           |
\**********************/

typedef struct {
	double x;
	double y;
	double z;
} __attribute__ ((packed)) CartVector_t;

typedef struct{
	float lat; // [deg]
	float lon; // [deg]
	float alt; // [m]
} __attribute__ ((packed))GPSLLA_t;

typedef struct{
	float lat; // [deg]
	float lon; // [deg]
} __attribute__ ((packed))GPSLatLon_t;

typedef struct{
	float value; // [m]
} __attribute__ ((packed))GPSAlt_t;

typedef struct{
	uint16_t year;
	uint8_t month;
	uint8_t day;
} __attribute__ ((packed))GPSDate_t;

typedef struct{
	uint8_t hours;
	uint8_t minutes;
	float seconds;
} __attribute__ ((packed))GPSUTC_t;

typedef struct{
	float tru;
	float magnetic;
} __attribute__ ((packed))GPSTrack_t;

typedef struct{
	float value;
} __attribute__ ((packed))GPSSOG_t;

typedef struct{
	uint8_t sats;
	uint8_t quality;
	float pdop;
} __attribute__ ((packed))GPSAccuracy_t;

typedef struct{
	GPSDate_t date;
	GPSUTC_t utc;
	GPSLLA_t pos;
	float track; // [deg]
	float sog;   // [m/s]
	GPSAccuracy_t accuracy;
} __attribute__ ((packed))GPSTelem_t;

/**********************\
|      air data        |
\**********************/

typedef struct{
	float ias;     // [m/s]
	float tas;     // [m/s]
	float pstatic; // [Pa]
	float pdynamic;// [Pa]
	float alt;     // [m]
} __attribute__ ((packed)) AirTelem_t;

typedef struct{
	float south;     // [m/s]
	float west;      // [m/s]
	GPSTelem_t gps;
} __attribute__ ((packed)) WindData_t;

/**********************\
|    communications    |
\**********************/
typedef struct 
{
	uint8_t  mac[6]; // mac of neighbor
	uint8_t  ip[4];  // ip of neighbor 

	float    signal;     // [dBm]
	float    noise;      // [dBm]
	float    channelCap;    // transmitt / receive capacity

	uint32_t  numBytesTx;    // number of bytes sent by comm [B]
	uint32_t  numBytesRx;    // number of bytes recieved by comm [B]

	float     rateTx;        // transmitted rate [B/s]
	float     rateRx;        // received rate [B/s]

	float    last_rx;    // [sec]
} __attribute__ ((packed)) LinkStatus_t;

typedef enum {
	NO_TEST = 0,
	UDP_TEST,
	TCP_TEST,
} TestType;

typedef struct 
{
	uint8_t  type; //  0->stop, 1->UDP, 2->TCP
	uint16_t time; // [sec] -- 0 to keep running 
} __attribute__ ((packed)) RateTest_t;

typedef struct {
	float rx_rate;
	float tx_rate;
} __attribute__ ((packed)) CommStatus_t;

typedef struct {
	in_addr ip;
	uint16_t port;
  bool connect;
} __attribute__ ((packed))CommStruct_t;


typedef struct {
  uint8_t beam;
} __attribute__ ((packed))PasCmd_t;

typedef enum {
  OMNI = 0,
  DIRECTIONAL,
  HOME,
} AntType;

typedef enum {
	MAGNETIC=0,
	ABSOLUTE,
	RELATIVE
} PointingType;

typedef struct {
	float azimuth;
	float elevation;
  uint8_t mode;
	uint8_t gs_telem:1;
	uint8_t tr_telem:1;
	uint8_t mag_telem:1;
	uint8_t tr_back_telem:1;
	uint8_t unusedBits: 4;
  uint8_t pointing_type;
} __attribute__ ((packed))AntPoint_t;

typedef struct {
	float offset;
} __attribute__ ((packed))AntSettings_t;

typedef struct {
	bool  launch_state;
} __attribute__ ((packed))AntState_t;

typedef struct {
  float magnetic_heading;
  float true_heading;
  float pitch;
  float roll;
} __attribute__ ((packed))MagStruct_t;

typedef struct {
  float rssi;
  GPSLLA_t gps;
} __attribute__ ((packed))RSSIStruct_t;


/**********************\
|       payload        |
\**********************/

typedef struct{
	float pressure;
	float temp;
	float internal_temp;
	float rh1;
	float rh2;
} __attribute__ ((packed)) PTH_t;

typedef struct{
	uint8_t    id;
	GPSTelem_t gps;
	PTH_t      pth;
} __attribute__ ((packed)) Sonde_t;

/**********************\
|  health and status   |
\**********************/

typedef struct{
	int8_t   availableForCommand;
	uint16_t twelveV; // [mV]
	uint16_t twelveA; // [mA]
	uint16_t fiveV;   // [mV]
	uint16_t fiveA;   // [mA]
	int8_t   boardT;  // [deg c]
	int8_t   RSSI;    // [dBm]
} __attribute__ ((packed))SysDiag_t;

typedef struct{
	uint8_t deadman:1;
	uint8_t gpsTimeout:1;
	uint8_t commTimeout:1;
	uint8_t aeroTermination:1;
	uint8_t flightTermination:1;
	uint8_t manual_engineKill:1;
	uint8_t auto_engineKill:1;
	uint8_t operator_engineKill:1;
} __attribute__ ((packed))FailureBits_t;

typedef struct{
	uint16_t altitudeHigh: 1;
	uint16_t altitudeLow: 1;
	uint16_t IASHigh: 1;
	uint16_t IASLow: 1;
	uint16_t rollHigh: 1;
	uint16_t pitchHigh: 1;
	uint16_t RPMLow: 1;
	uint16_t RPMHigh: 1;
	uint16_t windsHigh: 1;
	uint16_t unusedBits: 7;
} __attribute__ ((packed))Limits_t;

typedef struct {
	uint8_t  bumps_wheeldrops;
	uint8_t  wall;
	uint8_t  cliff_left;
	uint8_t  cliff_front_left;
	uint8_t  cliff_front_right;
	uint8_t  cliff_right;
	uint8_t  virtual_wall;
	uint8_t  motor_overcurrents;
	uint8_t  dirt_detector_left;
	uint8_t  dirt_detector_right;
} SCISensorPacket1_t;

typedef struct {
	uint8_t remote_opcode;
	uint8_t buttons;
	int16_t distance;
	int16_t angle;
} SCISensorPacket2_t;

typedef struct {
	uint8_t  charging_state;
	uint16_t voltage;
	int16_t  current;
	int8_t   temperature;
	uint16_t charge;
	uint16_t capacity;
} SCISensorPacket3_t;

typedef struct {
	SCISensorPacket1_t group_1;
	SCISensorPacket2_t group_2;
	SCISensorPacket3_t group_3;
	float time;
} __attribute__ ((packed))SCISensorPacket_t;

/**********************\
|      autopilot       |
\**********************/


//-- Piccolo AP --//
// Autopilot Mode for Fixed Wing Gen 2 Controller
enum PiccoloAPMode { AP_PRELAUNCH=0, AP_TRANSISTION, AP_LIFTFOFF, 
	AP_CLIMBOUT, AP_FLYING, AP_LANDING, AP_FINAL, 
	AP_SHORTFINAL, AP_TOUCHDOWN, AP_ROLLOUT};

// defined in SDK/PiccoloDefinitions.h
enum PiccoloMAMode { APMA_STANDARD=0, APMA_LATERAL, APMA_LONGITUDINAL, APMA_ALL  };

//-- Onboard Controller --//
// Use our own mode and type version, designate mode of our onboard controller
// and type of controller running
enum OBMode { OB_OFF=0, OB_INIT, OB_ORBIT, OB_WAYPT, OB_TURNRATE, OB_HEADING, OB_ERROR};
enum OBType { OB_NONE=0, OB_TRACK, OB_COOP_TRACK, OB_CHAIN, OB_STACK };

typedef struct{
	unsigned APon:1;
	unsigned MAmode:2;
	unsigned APmode:5;
	uint8_t waypt;
	unsigned OBmode:4;
	unsigned OBtype:4;
	float    value;     // used by high-level controllers
	uint8_t  targetAltCmd;
	float    targetAlt;
	uint8_t  targetIASCmd;
	float    targetIAS;
} __attribute__ ((packed))NavigationStatus_t;

typedef struct {
	uint8_t     number;
	uint8_t     next;
	int16_t     orbitRad; // [m] (-) radius is right hand (CW), pos (+) is left (CCW)
	GPSLLA_t    pos;
} __attribute__ ((packed))Waypt_t;

typedef struct {
	uint8_t     ind;
} __attribute__ ((packed))GotoWP_t;

typedef struct {
	uint8_t   control;
	float     value;
} __attribute__ ((packed))GotoIAS_t;

typedef struct {
	uint8_t   control;
	float     value;
} __attribute__ ((packed))GotoAlt_t;

typedef struct {
	uint8_t   control;
	float     value;
} __attribute__ ((packed))GotoBank_t;

// since track, and gps lat lon are in deg, should have angles in deg
// its only 6 extra bytes
typedef struct {
	float roll;  // [deg]
	float pitch; // [deg]
	float yaw;   // [deg]
} __attribute__ ((packed))Angles_t;

typedef struct {
	uint16_t           address;
	GPSTelem_t         gps;
	AirTelem_t         airdata;
	IMUAngles_t        angles;
	NavigationStatus_t navigation;
	SysDiag_t          system;
	FailureBits_t      failure;
	Limits_t           limits;
	Servos_t           servos;
} __attribute__ ((packed))Telemetry_t;

typedef struct {
	float turn_rate;// [deg/s]
	float velocity; // [m/s]
} __attribute__ ((packed))APRates_t;

typedef struct {
	float kv;   // []
	float vmax; // [m/s]
	int   mode; // contrller mode, 0->minimax, 1->RR
} __attribute__ ((packed))ChainGains_t;

// [m]
#define ORBIT_ALT      1770 
#define ORBIT_DIR      1
#define ORBIT_RADIUS   150 
#define ORBIT_WAYPOINT 30 
typedef struct _OrbitValues_t{
	float   rad; // orbit at this radius
	float   alt; // orbit at this alt
	uint8_t wp;  // waypoint
	int8_t  dir; // direction [+/- 1] -> +1 CW, -1 CCW
	float  offset[2];  //offset in meters


	_OrbitValues_t () {
		alt = ORBIT_ALT;
		rad = ORBIT_RADIUS;
		wp  = ORBIT_WAYPOINT;
		dir = ORBIT_DIR;
		offset[0] = 0;
		offset[1] = 0;
	}
} __attribute__ ((packed))OrbitValues_t;


/**********************\
|   flight computer    |
\**********************/

typedef struct {
	in_addr partner;
	bool requesting;
} __attribute__ ((packed))Coordinate_t;

typedef struct {
	in_addr parent;
	bool requesting;
} __attribute__ ((packed))Custody_t;

typedef struct {
	float angle;
} __attribute__ ((packed))Phase_t;

typedef struct _Target_t{
  GPSLLA_t pos;
	bool targeted;

	_Target_t () {
		targeted = false;
	}
} __attribute__ ((packed))Target_t;

typedef struct {
	Target_t targets[4];
} __attribute__ ((packed))TargetStatus_t;

/**********************\
|     system wide      |
\**********************/

typedef struct {
	char id [32]; // name string
} __attribute__ ((packed))VehicleInfo_t;

typedef struct {
	uint8_t  id;
	uint16_t commands;
	uint16_t streams;
	uint8_t  range;
	float    fov;
	float    direction;
} __attribute__ ((packed))SystemCharacter_t;

typedef struct {
	uint8_t  id;
	in_addr  client;
	uint16_t port;
	bool     send_data;
} __attribute__ ((packed))StreamReq_t;

/**********************\
|   Deploy Mechanism   |
\**********************/

enum DMStatus_t
{ 
  DM_ERROR=0, 
  DM_EMPTY, 
  DM_LOADED,
};

typedef struct {
  char id[NAME_STRING_LEN];
  DMStatus_t status;
} __attribute__ ((packed))DeployMechanism_t;

typedef struct {
  int peg;
} __attribute__ ((packed))DMDeploy_t;

/**********************\
|      DM Setup        |
\**********************/

typedef struct {
  DeployMechanism_t pegs[NUM_DEPLOY_MECHANISMS]; // NUM_...defined above
} __attribute__ ((packed))Mothership_t;

/**********************\
|   NIDAQ Read/Write   |
\**********************/

enum NIDAQPortType_t
{ 
  ANALOG_IN,
  ANALOG_OUT,
  DIGITAL_IN,
  DIGITAL_OUT,
};

typedef struct {
  NIDAQPortType_t port_type;
  uint16_t command;
} __attribute__ ((packed))NIDAQAction_t;


/*<------End Defines------>*/

#endif //__SENSORSTRUCT_H
